package com.xlh.service.courseTest.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.xlh.constant.CourseTestConstant;
import com.xlh.dto.PageDTO;
import com.xlh.dto.course.ChapterBasicInfoDTO;
import com.xlh.dto.course.CourseDTO;
import com.xlh.dto.course.TemplateDataDTO;
import com.xlh.dto.course.ZtreeDTO;
import com.xlh.dto.courseTest.*;
import com.xlh.dto.user.UserInfoDTO;
import com.xlh.enums.FileTypeEnum;
import com.xlh.enums.course.ChapterEnum;
import com.xlh.enums.course.CourseSharedEnum;
import com.xlh.enums.course.TemplateTypeEnum;
import com.xlh.enums.courseTest.QuestionBusinessTypeEnum;
import com.xlh.enums.courseTest.QuestionTypeEnum;
import com.xlh.enums.user.RoleEnum;
import com.xlh.exception.CourseTestExceptionInfo;
import com.xlh.exception.common.GlobalException;
import com.xlh.param.courseTest.QuestionAnswerParam;
import com.xlh.param.courseTest.QuestionRepositoryAddQuestionParam;
import com.xlh.param.courseTest.QuestionRepositoryUpdateQuestionParam;
import com.xlh.pojo.course.ChapterBasic;
import com.xlh.pojo.course.Course;
import com.xlh.pojo.courseTest.CourseQuestionRepository;
import com.xlh.pojo.courseTest.CourseQuestionRepositoryDetails;
import com.xlh.pojo.courseTest.CourseQuestionRepositoryExample;
import com.xlh.pojo.courseTest.CourseTestPaperClass;
import com.xlh.security.UserInfoHolder;
import com.xlh.service.ExcelService;
import com.xlh.service.course.ChapterService;
import com.xlh.service.course.CourseService;
import com.xlh.service.course.TemplateService;
import com.xlh.service.courseTest.*;
import com.xlh.service.user.UserService;
import com.xlh.util.BeanUtil;
import com.xlh.util.ExcelsUtil;
import com.youbenzi.md2.util.MDUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhr 2019/4/26
 */
@Service
public class RepositoryServiceImpl implements RepositoryService {

    @Autowired
    private ChapterService chapterService;
    @Autowired
    private QuestionRepositoryService questionRepositoryService;
    @Autowired
    private QuestionRepositoryDetailsService questionRepositoryDetailsService;
    @Autowired
    private TemplateService templateService;
    @Autowired
    private ExcelService excelService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private RepositoryImportService repositoryImportService;
    @Autowired
    private UserService userService;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Override
    public QuestionRepositoryDropdownListDTO dropdownList(Long courseId, Integer businessType, Integer type) {
        QuestionRepositoryDropdownListDTO resultDTO = new QuestionRepositoryDropdownListDTO();
        if (type == 1) {
            // 封装章节信息
            resultDTO.setChapterList(chapterList(Lists.newArrayList(courseId)));
        } else {
            resultDTO.setChapterList(chapterListOwner(Lists.newArrayList(courseId)));
        }
        // 封装题型下拉框内容
        resultDTO.setQuestionTypeList(QuestionTypeEnum.getQuestionTypeList(businessType));

        return resultDTO;
    }

    @Override
    public PageDTO<QuestionListDTO> questionList(Integer pageNum, Integer pageSize, String keyWord, Long courseId, Long chapterId, Integer questionType, Integer businessType, Integer type) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();

        PageHelper.startPage(pageNum, pageSize);
        List<QuestionListDTO> list = questionRepositoryService.questionListOther(
                keyWord, courseId, chapterId, questionType, businessType, userId, null
        );

        if (CollectionUtils.isNotEmpty(list)) {
            // 获取答案描述
            List<Long> questionIds = list.stream().map(QuestionListDTO::getId)
                    .collect(Collectors.toList());
            Map<Long, List<CourseQuestionRepositoryDetails>> detailsListMap = questionRepositoryDetailsService.getDetailsMap(questionIds, FileTypeEnum.HTML);

            // 封装答案集合，题目来源文字描述
            setQuestionListDTO(list, detailsListMap, null, questionIds);
        }
        PageInfo<QuestionListDTO> pageInfo = new PageInfo<>(list);
        return new PageDTO<>(pageInfo);
    }

    @Override
    @Transactional
    public Long addQuestion(Long courseId, Integer businessType, QuestionRepositoryAddQuestionParam param) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();
        UserInfoDTO userInfo = userService.getUserInfo(userId, null);
        boolean isTeacher = isTeacher(userInfo.getRole());

        QuestionTypeEnum typeEnum = QuestionTypeEnum.forCode(param.getQuestionType());

        if (typeEnum == null) {
            throw new GlobalException("请选择题目题型");
        }

        // 检查答案及选项填写情况
        typeEnum.checkQuestionAnswer(param.getAnswer());

        // 插入题干信息
        Long questionId = insertQuestion(courseId, businessType, param, userId, isTeacher);

        // 插入答案信息
        if(param.getAnswer() != null) {
        	insertAnswer(param.getAnswer(), questionId);
        }

        return questionId;
    }

    private boolean isTeacher(Integer role) {
        return Objects.equals(role, RoleEnum.TEACHER.getRoleCode()) || Objects.equals(role, RoleEnum.UNIVERSITY_TEACHER.getRoleCode()) ||
                Objects.equals(role, RoleEnum.MARKET_TEACHER.getRoleCode());
    }

    private void insertAnswer(List<QuestionAnswerParam> answer, Long questionId) {
        for (int i = 0; i < answer.size(); i++) {
            QuestionAnswerParam answerParam = answer.get(i);

            CourseQuestionRepositoryDetails details = new CourseQuestionRepositoryDetails();
            // 以循环指针值作为排序码
            details.setOrderNumber(i);
            details.setQuestionId(questionId);
            details.setIsCorrect(answerParam.getIsCorrect());
            details.setMdContent(answerParam.getContent());
            details.setHtmlContent(answerParam.getHtmlContent());

            questionRepositoryDetailsService.insertSelective(details);
        }
    }

    private Long insertQuestion(Long courseId, Integer businessType, QuestionRepositoryAddQuestionParam param, Long userId, Boolean isTeacher) {
        CourseQuestionRepository repository = new CourseQuestionRepository();
        repository.setCourseId(courseId);
        repository.setBusinessType(businessType);
        repository.setUserId(userId);
        repository.setChapterId(param.getChapterId());
        repository.setQuestionType(param.getQuestionType());
        repository.setMdContent(param.getContent());
        repository.setHtmlContent(param.getHtmlContent());
        repository.setIsPreset(!isTeacher);
        repository.setJxContent(param.getJxContent());
        repository.setJxContentHtml(param.getJxContentHtml());

        questionRepositoryService.insertSelective(repository);

        return repository.getId();
    }

    @Override
    public List<QuestionListDTO> presetQuestionList(String keyWord, Long courseDropdownId, Long courseId, Long chapterId, Integer questionType, Integer businessType) {
        // 使用查询条件查询出所有的预制试题
        List<QuestionListDTO> questionListDTOList = questionRepositoryService.questionList(keyWord, courseDropdownId, chapterId, questionType, businessType, null, true);
        if (CollectionUtils.isEmpty(questionListDTOList)) {
            return Lists.newArrayList();
        }

        // 查询当前教师在当前课程下所有导入的试题id
        List<Long> presetQuestionIds = questionListDTOList.stream().map(QuestionListDTO::getId).collect(Collectors.toList());
        List<Long> userQuestionSourceQuestionIds = getTeacherUsedQuestionId(presetQuestionIds, courseId, userInfoHolder.getUserId());

        // 获取答案描述
        Map<Long, List<CourseQuestionRepositoryDetails>> detailsListMap = questionRepositoryDetailsService.getDetailsMap(presetQuestionIds, FileTypeEnum.HTML);

        // 当前已选中的题目id
        List<Long> ids = repositoryImportService.getCache(courseId);

        // 封装答案集合，题目来源文字描述，题目被导入情况
        setQuestionListDTO(questionListDTOList, detailsListMap, userQuestionSourceQuestionIds, ids);

        return questionListDTOList;
    }

    @Override
    @Transactional
    public void importFromPreset(Long courseId, Integer businessType, List<Long> questionIds) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();
        UserInfoDTO userInfo = userService.getUserInfo(userId, null);
        boolean isTeacher = isTeacher(userInfo.getRole());

        if (CollectionUtils.isEmpty(questionIds)) {
            throw new GlobalException("请选择试题");
        }

        // 获取选定题目列表
        List<CourseQuestionRepository> questionList = questionRepositoryService.selectQuestionByIds(questionIds);
        if (CollectionUtils.isEmpty(questionList)) {
            throw new GlobalException("无法获取相应题目");
        }
        // 清空题目章节
        questionList.forEach(question -> question.setChapterId(null));

        // 查询所有的预制答案
        Map<Long, List<CourseQuestionRepositoryDetails>> presetDetailsListMap = questionRepositoryDetailsService.getDetailsMap(questionIds);

        // 为了减少mapper的反复调用，使用mybatis批处理，需要手动添加题目id
        // 获取主表中当前id的最大值
        questionRepositoryService.importQuestion(courseId, userId, isTeacher, true, questionList, presetDetailsListMap);

        // 清空缓存记录
        repositoryImportService.removeAllCache(courseId);
    }

    @Override
    public void getExcelModel(HttpServletResponse res, HttpServletRequest req, Integer businessType) {
        boolean isTest = Objects.equals(businessType, QuestionBusinessTypeEnum.TEST.getCode());
        String fileName = isTest ? "考试题库导入模板.xls" : "随堂练习题库导入模板.xls";
        String modelPosition = isTest ?
                CourseTestConstant.TEST_EXCEL_MODEL_PATH : CourseTestConstant.PRACTICE_EXCEL_MODEL_PATH;
        try {
            excelService.downloadExcelModel(res, req, fileName, modelPosition);
        } catch (Exception e) {
            throw new GlobalException("找不到指定的excel文件");
        }
    }

    @Override
    @Transactional
    public void importFromExcel(MultipartFile file, Long courseId, Integer businessType) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();
        UserInfoDTO userInfo = userService.getUserInfo(userId, null);
        boolean isTeacher = isTeacher(userInfo.getRole());

        if (file == null) {
            throw new GlobalException("请上传excel文件");
        }

        if (!isExcel(file.getOriginalFilename())) {
            throw new GlobalException("请上传excel文件");
        }

        List<QuestionExcelDataDTO> excelDataDTOList = ExcelsUtil.readExcelData(
                file, CourseTestConstant.TEST_EXCEL_HEADER, 1, 2, QuestionExcelDataDTO.class
        );

        if (CollectionUtils.isEmpty(excelDataDTOList)) {
            throw new GlobalException("excel模板无数据或excel不合法");
        }

        // 导入数据
        importExcelData(excelDataDTOList, userId, isTeacher, businessType, courseId, null);
    }

    private void importExcelData(List<? extends PracticeQuestionExcelDataDTO> excelDataDTOList, Long userId, Boolean isTeacher, Integer businessType, Long courseId, Long chapterId) {
        int listSize = excelDataDTOList.size();

        List<ChapterBasic> chapterBasics = chapterService.getChapterBasic(
                courseId, null, null, ChapterEnum.CHAPTER);
        Map<String, Long> chapterNameIdMap = chapterBasics.stream().collect(Collectors.toMap(
                ChapterBasic::getName, ChapterBasic::getId, (value1, value2) -> value1
        ));

        // 题目信息列表
        List<CourseQuestionRepository> repositoryList = Lists.newArrayList();
        // 答案信息列表
        List<CourseQuestionRepositoryDetails> detailsList = Lists.newArrayList();
        for (int i = 0; i < listSize; i++) {
            Map<String, Object> map = cn.hutool.core.bean.BeanUtil.beanToMap(excelDataDTOList.get(i));
            if (map.get("orderNumber") == null) {
                throw new GlobalException("编号不能为空");
            }
            if (map.get("question") == null) {
                throw new GlobalException("题干信息不能为空");
            }
            String question = map.get("question").toString();
            if (StringUtils.isBlank(question)) {
                throw new GlobalException("题干信息不能为空");
            }
            if (map.get("answer") == null) {
                throw new GlobalException("答案信息不能为空");
            }
            String answer = map.get("answer").toString();
            if (StringUtils.isBlank(answer)) {
                throw new GlobalException("答案信息不能为空");
            }

            if (map.get("typeName") == null) {
                throw new GlobalException("请选择题型");
            }

            QuestionTypeEnum typeEnum = QuestionTypeEnum.forMessage(map.get("typeName").toString());
            if (typeEnum == null) {
                throw new GlobalException("请按照模板要求题型格式填写题型");
            }

            Long chapterResultId = map.get("chapterName") == null ? chapterId : chapterNameIdMap.get(map.get("chapterName").toString());

            question = question.replace("*", "\\*");

            repositoryList.add(new CourseQuestionRepository(userId, courseId, businessType, !isTeacher, typeEnum.getCode(), question, MDUtil.markdown2Html(question), chapterResultId));
        }

        // 批量插入题干,取得返回的主键id
        questionRepositoryService.insertBatch(repositoryList);

        for (int i = 0; i < listSize; i++) {
            Map<String, Object> map = cn.hutool.core.bean.BeanUtil.beanToMap(excelDataDTOList.get(i));
            CourseQuestionRepository repository = repositoryList.get(i);

            QuestionTypeEnum typeEnum = QuestionTypeEnum.forCode(repositoryList.get(i).getQuestionType());
            if (typeEnum == null) {
                throw new GlobalException("请按照模板要求题型格式填写题型");
            }
            List<CourseQuestionRepositoryDetails> answerList = typeEnum.setObject(map, repository.getId());
            detailsList.addAll(answerList);
        }

        questionRepositoryDetailsService.insertBatch(detailsList);
    }

    @Override
    @Transactional
    public void importFromExcel(MultipartFile file, Long courseId, Integer businessType, Long chapterId) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();
        UserInfoDTO userInfo = userService.getUserInfo(userId, null);
        boolean isTeacher = isTeacher(userInfo.getRole());

        if (file == null) {
            throw new GlobalException("请上传excel文件");
        }

        if (!isExcel(file.getOriginalFilename())) {
            throw new GlobalException("请上传excel文件");
        }

        List<PracticeQuestionExcelDataDTO> excelDataDTOList = ExcelsUtil.readExcelData(
                file, CourseTestConstant.PRACTICE_EXCEL_HEADER, 1, 2, PracticeQuestionExcelDataDTO.class
        );

        List<String> typeNameList = excelDataDTOList.stream().map(PracticeQuestionExcelDataDTO::getTypeName).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(typeNameList) && typeNameList.contains(QuestionTypeEnum.EXPERIMENT.getMessage())) {
            throw new GlobalException("无法解析题目类型");
        }

        if (CollectionUtils.isEmpty(excelDataDTOList)) {
            throw new GlobalException("excel模板无数据或excel不合法");
        }

        // 导入数据
        importExcelData(excelDataDTOList, userId, isTeacher, businessType, courseId, chapterId);
    }

    @Override
    public QuestionListDTO showUpdateQuestion(Long courseId, Long questionId) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();

        // 获取题干基本信息
        CourseQuestionRepository repository = questionRepositoryService.selectByPrimaryKey(questionId);

        // 获取答案基本信息
        List<CourseQuestionRepositoryDetails> detailsList = questionRepositoryDetailsService.getDetailsList(Lists.newArrayList(questionId), FileTypeEnum.MARKDOWN);

        if (Objects.equals(QuestionTypeEnum.EXPERIMENT.getCode(), repository.getQuestionType())) {
            TemplateDataDTO templateInfo = templateService.queryTemplate(userId, TemplateTypeEnum.TEST_REPORT);
            return new QuestionListDTO().convert(repository, detailsList, templateInfo);
        }

        // 转化结果
        return new QuestionListDTO().convert(repository, detailsList, null);
    }

    @Override
    @Transactional
    public void updateQuestion(Long courseId, Long questionId, QuestionRepositoryUpdateQuestionParam param) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();
        UserInfoDTO userInfo = userService.getUserInfo(userId, null);
        boolean isTeacher = isTeacher(userInfo.getRole());

        CourseQuestionRepository question = questionRepositoryService.selectByPrimaryKey(questionId);

        QuestionTypeEnum typeEnum = QuestionTypeEnum.forCode(question.getQuestionType());
        if (typeEnum == null) {
            throw new GlobalException("无法解析题目类型");
        }

        // 检查答案及选项填写情况
        typeEnum.checkQuestionAnswer(param.getAnswer());

        // 判断选择的题目是否归属于登录教师
        if (!Objects.equals(question.getUserId(), userId)) {
            throw new GlobalException(CourseTestExceptionInfo.NOT_USER_QUESTION);
        }

        // 教师身份需要判断选定题目是否为预制题目
        if (isTeacher && question.getIsPreset()) {
            throw new GlobalException(CourseTestExceptionInfo.CANNOT_OPERATE_PRESET_QUESTION);
        }

        // 修改题干
        updateQuestionRepository(question, param);

        // 修改答案
        updateQuestionDetails(questionId, param);
    }

    private void updateQuestionRepository(CourseQuestionRepository question, QuestionRepositoryUpdateQuestionParam param) {
        question.setSourceQuestionId(null);
        question.setMdContent(param.getContent());
        question.setHtmlContent(param.getHtmlContent());
        question.setChapterId(param.getChapterId());
        question.setJxContentHtml(param.getJxContentHtml());
        question.setJxContent(param.getJxContent());

        questionRepositoryService.updateByPrimaryKeySelective(question);
    }

    private void updateQuestionDetails(Long questionId, QuestionRepositoryUpdateQuestionParam param) {
        // 删除旧的答案信息（直接物理删除，因为旧的答案信息在现在的需求中没有作用）
        questionRepositoryDetailsService.deleteByQuestionId(questionId);

        // 将新的答案信息覆盖上
        List<QuestionAnswerParam> answerParamList = param.getAnswer();
        insertAnswer(answerParamList, questionId);
    }

    @Override
    @Transactional
    public void deleteQuestion(Long courseId, List<Long> questionIds) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();
        UserInfoDTO userInfo = userService.getUserInfo(userId, null);
        boolean isTeacher = isTeacher(userInfo.getRole());

        if (CollectionUtils.isEmpty(questionIds)) {
            throw new GlobalException("请选择至少一项后进行删除");
        }
        // 获取选定题目列表
        List<CourseQuestionRepository> courseQuestionRepositoryList = questionRepositoryService.selectQuestionByIds(questionIds);

        // 判断选择的题目是否全部归属于登录教师
        if (hasQuestionNoAuthorization(courseQuestionRepositoryList, userId)) {
            throw new GlobalException(CourseTestExceptionInfo.NOT_USER_QUESTION);
        }

        // 教师身份需要判断选定题目是否包含预制题目
        if (isTeacher && containsPreset(courseQuestionRepositoryList)) {
            throw new GlobalException(CourseTestExceptionInfo.CANNOT_OPERATE_PRESET_QUESTION);
        }

        // 删除主表内容
        questionRepositoryService.updateDeleteByIds(questionIds);

        // 删除答案表内容
        questionRepositoryDetailsService.updateDelete(questionIds);
    }

    private boolean containsPreset(List<CourseQuestionRepository> questionList) {
        Set<Boolean> isPresetSet = questionList.stream().map(CourseQuestionRepository::getIsPreset)
                .collect(Collectors.toSet());
        return isPresetSet.contains(true);
    }

    private boolean hasQuestionNoAuthorization(List<CourseQuestionRepository> questionList, Long userId) {
        Set<Long> userIdSet = questionList.stream().map(CourseQuestionRepository::getUserId).collect(Collectors.toSet());
        return !(userIdSet.size() == 1 && userIdSet.contains(userId));
    }

    @Override
    public List<TypeQuestionListDTO> listQuestionByType(Long chapterId, Long courseId, Integer businessType) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();

        // 查询题目列表
        List<QuestionListDTO> questionListDTOList = questionRepositoryService.questionListOther(
                null, courseId, chapterId, null, businessType, userId, null
        );

        // 获取答案描述
        List<Long> questionIds = questionListDTOList.stream().map(QuestionListDTO::getId)
                .collect(Collectors.toList());
        Map<Long, List<CourseQuestionRepositoryDetails>> detailsListMap = questionRepositoryDetailsService.getDetailsMap(questionIds, FileTypeEnum.HTML);

        // 封装答案集合，题目来源文字描述
        setQuestionListDTO(questionListDTOList, detailsListMap, null, questionIds);

        // 将结果集转化为所需格式
        return convert(questionListDTOList);
    }

    @Override
    public List<ZtreeDTO> getCourseChapterList() {
        // 查询已发布的课程
        List<CourseDTO> courseList = courseService.listCourse(CourseSharedEnum.ALL);

        // 查询所有课程的章节
        List<Long> courseIds = courseList.stream().map(CourseDTO::getId).collect(Collectors.toList());
        List<ChapterBasicInfoDTO> chapterList = chapterList(courseIds);
        List<ZtreeDTO> chapterZtreeList = BeanUtil.batchTransform(ZtreeDTO.class, chapterList);
        Map<Long, List<ZtreeDTO>> courseIdChapterZtreeList = BeanUtil.aggByKeyToList("courseId", chapterZtreeList);

        // 课程列表转化为ZTree
        List<ZtreeDTO> courseZtreeList = BeanUtil.batchTransform(ZtreeDTO.class, courseList);
        courseZtreeList.forEach(dto -> dto.setChildren(courseIdChapterZtreeList.get(dto.getId())));

        return courseZtreeList;
    }

    @Override
    public List<ChapterBasicInfoDTO> chapterListOwner(List<Long> courseIds) {
        String format = "第%d章 %s";
        final int[] count = {1};
        List<ChapterBasicInfoDTO> chapterList = chapterService.listChapter(
                Lists.newArrayList(courseIds), null, null, ChapterEnum.CHAPTER);
        List<ChapterBasicInfoDTO> chapterListnew = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(chapterList)) {
            chapterList.forEach(chapter -> {
                if (Objects.equals(chapter.getFalg(), 0)) {
                    chapter.setName(String.format(format, count[0], chapter.getName()));
                    chapterListnew.add(chapter);
                    count[0]++;
                }
            });
        }
        return chapterListnew;
    }

    @Override
    public List<ChapterBasicInfoDTO> chapterList(List<Long> courseIds) {
        String format = "第%d章 %s";
        List<ChapterBasicInfoDTO> chapterList = chapterService.listChapter(
                Lists.newArrayList(courseIds), null, null, ChapterEnum.CHAPTER);
        if (CollectionUtils.isNotEmpty(chapterList)) {
            chapterList.forEach(chapter -> chapter.setName(String.format(format, chapter.getOrderNumber(), chapter.getName())));
        }
        return chapterList;
    }

    @Override
    public List<QuestionListDTO> presetChosenList(Long courseId) {
        List<Long> ids = repositoryImportService.getCache(courseId);

        if (CollectionUtils.isEmpty(ids)) {
            return Lists.newArrayList();
        }

        // 查询题目列表
        List<QuestionListDTO> questionListDTOList = questionRepositoryService.questionListByIds(ids);

        if (CollectionUtils.isNotEmpty(questionListDTOList)) {
            // 获取答案描述
            Map<Long, List<CourseQuestionRepositoryDetails>> detailsListMap = questionRepositoryDetailsService.getDetailsMap(ids, FileTypeEnum.HTML);

            // 封装答案集合，题目来源文字描述
            setQuestionListDTO(questionListDTOList, detailsListMap, null, null);
            questionListDTOList.forEach(questionListDTO -> questionListDTO.convert(detailsListMap));
            return questionListDTOList;
        } else {
            return Lists.newArrayList();
        }
    }

    private List<TypeQuestionListDTO> convert(List<QuestionListDTO> questionListDTOList) {
        List<TypeQuestionListDTO> resultList = Lists.newArrayList();
        Map<Integer, List<QuestionListDTO>> questionListTypeMap = BeanUtil.aggByKeyToList("questionType", questionListDTOList);
        questionListTypeMap.forEach((type, list) -> {
            QuestionTypeEnum typeEnum = QuestionTypeEnum.forCode(type);
            String typeMessage = null;
            if (typeEnum != null) {
                typeMessage = typeEnum.getMessage();
            }
            resultList.add(new TypeQuestionListDTO(type, typeMessage, list));
        });
        return resultList;
    }

    private void setQuestionListDTO(List<QuestionListDTO> list, Map<Long, List<CourseQuestionRepositoryDetails>> detailsListMap, List<Long> userQuestionIds, List<Long> chosenIds) {
        for (QuestionListDTO dto : list) {
            dto.convert(detailsListMap, userQuestionIds, chosenIds);
        }
    }

    private List<Long> getTeacherUsedQuestionId(List<Long> presetQuestionIds, Long courseId, Long userId) {
        // 查询教师已经导入的题目id
        CourseQuestionRepositoryExample example = new CourseQuestionRepositoryExample();
        CourseQuestionRepositoryExample.Criteria userQuestionCriteria = example.createCriteria();
        userQuestionCriteria.andCourseIdEqualTo(courseId).andUserIdEqualTo(userId).andDelMarkEqualTo(false);
        if (CollectionUtils.isNotEmpty(presetQuestionIds)) {
            userQuestionCriteria.andSourceQuestionIdIn(presetQuestionIds);
        }
        List<CourseQuestionRepository> userQuestionList = questionRepositoryService.selectByExample(example);

        // 转换并返回结果
        return userQuestionList.stream().map(CourseQuestionRepository::getSourceQuestionId).collect(Collectors.toList());
    }

    /**
     * 根据文件名判断是否为excel文件
     *
     * @param fileName 待判断文件名称
     * @return 判断结果
     */
    private boolean isExcel(String fileName) {
        try {
            String extension = fileName.substring(fileName.lastIndexOf("."));
            return StringUtils.equals(".xls", extension) || StringUtils.equals(".xlsx", extension);
        } catch (StringIndexOutOfBoundsException e) {
            return false;
        }
    }
}
